package beautiful.butterfly.execute_engine;

import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Future;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class CallableContext {
    private Map<Callable, CallableContext> callableToCallableContextMap;
    private Callable callable;
    private Future future;
    //


    //控制暂停
    public volatile boolean isRun = true;
    private volatile ReentrantLock reentrantLock = new ReentrantLock();
    private volatile Condition condition = reentrantLock.newCondition();


    //
    //是否串行模式(true),默认是并行模式(false)
    private volatile boolean sequence = false;
    private CountDownLatch countDownLatch = null;

    //
    public CallableContext(Map<Callable, CallableContext> callableToCallableContextMap, Callable callable, Future future) {
        this.callableToCallableContextMap = callableToCallableContextMap;
        this.callable = callable;
        this.future = future;
    }

    //
    public void setCallableToCallableContextMap(Map callableToCallableContextMap) {
        this.callableToCallableContextMap = callableToCallableContextMap;
    }

    public Map getCallableToCallableContextMap() {
        return callableToCallableContextMap;
    }

    //
    public void setCallable(Callable callable) {
        this.callable = callable;
    }

    public Callable getCallable() {
        return callable;
    }

    //
    public void setFuture(Future future) {
        this.future = future;
    }

    public Future getFuture() {
        return future;
    }

    //
    public void setNotRun() throws InterruptedException {
        this.isRun = false;
        System.out.println("setNotRun");
    }

    public void setRun() throws InterruptedException {
        this.isRun = true;
        //
        System.out.println("setRun start");
        this.reentrantLock.lock();
        this.condition.signal();
        this.reentrantLock.unlock();
        System.out.println("setRun end");
    }

    public void checkRun() throws InterruptedException {
        System.out.println("checkRun start");
        if (!this.isRun) {
            this.reentrantLock.lock();
            System.out.println("this.condition.await(); start");
            this.condition.await();
            System.out.println("this.condition.await(); end");
            this.reentrantLock.unlock();
        } else {
            System.out.println("isRun ...true");
        }
        System.out.println("checkRun end");
    }

    //中断功能
    private volatile boolean isNeedInterruptIfRunning = false;

    public void setNeedInterruptIfRunning(boolean needInterruptIfRunning) {
        isNeedInterruptIfRunning = needInterruptIfRunning;
    }

    public boolean isNeedInterruptIfRunning() {
        return isNeedInterruptIfRunning;
    }

    //
    public void checkWhetherNeedInterruptIfRunning() throws InterruptedException {
        if (this.isNeedInterruptIfRunning) {
            this.callableToCallableContextMap.remove(this.callable);
            throw new InterruptedException();
        }
    }

    //日志跟踪功能
    private List<Track> trackList = new LinkedList<Track>();

    public void addTrack(Track track) {
        this.trackList.add(track);
    }

    public List<Track> getTrackList() {
        return this.trackList;
    }

    public void clearTrackList() {
        this.trackList.clear();
    }

    //
    public void setSequence() {
        if (countDownLatch != null) {
            throw new RuntimeException("can not fix sequence");
        }
        this.sequence = true;
        this.countDownLatch = new CountDownLatch(1);
    }

    public boolean isSequence() {
        return sequence;
    }

    //
    public void countDown() {
        if (this.sequence) {
            this.countDownLatch.countDown();
        }

    }

    public void await() throws InterruptedException {
        if (this.sequence) {
            this.countDownLatch.await();
        }

    }
}
